package com.yjf.ljr.connection;

/*
 * 功能描述：网络请求模块,采用HttpClient方式
 *	1.支持同步和异步
 *	2.支持GET和POST
 *
 */
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;

import android.os.Handler;
import android.os.Message;

import com.yjf.ljr.common.CommonData;
import com.yjf.ljr.common.Logger;
import com.yjf.ljr.util.Base64;
import com.yjf.ljr.util.HMacMD5;

public class NwConnect {

	private static final int PARSE_JSON = 0x0001;
	private HttpConnCallback mCallBack;

	public static enum HttpMethod {
		GET, POST
	}
	
	/**
	 * Title: 异步请求
	 * <p>Description:</p>
	 * @param url
	 * @param strBody
	 * @param method
	 * @param callback
	 */
	public void asyncConnect(final String url, final String strBody, final HttpMethod method, HttpConnCallback callback) {
		this.mCallBack = callback;
		new Thread() {
			@Override
			public void run() {
				String json = null;
				HttpUriRequest httpUrlReq = null;
				try {
					HttpParams httpParameters = new BasicHttpParams();
					HttpConnectionParams.setConnectionTimeout(httpParameters, 15000);// 设置连接超时
					HttpConnectionParams.setSoTimeout(httpParameters, 15000);
					HttpClient client = new DefaultHttpClient(httpParameters);
					
					if (method.equals(HttpMethod.POST)) {
						HttpPost reqPost = new HttpPost(url);
						reqPost.addHeader("Content-Type", "application/json");
						reqPost.setEntity(new StringEntity(strBody, HTTP.UTF_8));
						httpUrlReq = reqPost;
					} else {
						httpUrlReq = new HttpGet(url);
					}
					HttpResponse httpResponse = client.execute(httpUrlReq);
					if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
						json = EntityUtils.toString(httpResponse.getEntity());
					}
				} catch (Exception e) {
					e.printStackTrace();
				}

				Message msg = new Message();
				msg.what = PARSE_JSON;
				msg.obj = json;
				NwConnect.this.hdl.sendMessage(msg);
			}
		}.start();
	}

	/**
	 * 异步请求
	 * 
	 * @param url
	 * @param strParams
	 *            字符串参数
	 * @param fileParams
	 *            文件参数,例如:图片
	 * @param method
	 *            请求方法,GET或者POST
	 * @param callback
	 *            处理服务器返回的回调
	 */
	public void asyncConnect(final String url, final Map<String, String> strParams, final Map<String, String> fileParams, final HttpMethod method,
			HttpConnCallback callback) {
		this.mCallBack = callback;
		new Thread() {
			@Override
			public void run() {
				String json = null;
				BufferedReader reader = null;
				try {
					HttpParams httpParameters = new BasicHttpParams();
					HttpConnectionParams.setConnectionTimeout(httpParameters, 15000);// 设置连接超时
					HttpConnectionParams.setSoTimeout(httpParameters, 15000);
					HttpClient client = new DefaultHttpClient(httpParameters);
					HttpUriRequest request = getRequest(url, strParams, fileParams, method);
					if (request == null) {
						Logger.e("Connect", "invalid request params");
						return;
					}
					HttpResponse response = client.execute(request);
					if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
						reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
						StringBuilder sb = new StringBuilder();
						for (String s = reader.readLine(); s != null; s = reader.readLine()) {
							sb.append(s);
						}
						json = sb.toString();
					}
				} catch (ClientProtocolException e) {
					Logger.e("Connect", e.getMessage(), e);
				} catch (IOException e) {
					Logger.e("Connect", e.getMessage(), e);
				} finally {
					try {
						if (reader != null) {
							reader.close();
						}
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
				Message msg = new Message();
				msg.what = PARSE_JSON;
				msg.obj = json;
				NwConnect.this.hdl.sendMessage(msg);
			}
		}.start();
	}

	/**
	 * 组装请求的参数
	 * 
	 * @param url
	 * @param strParams
	 * @param fileParams
	 * @param method
	 * @return
	 */
	private HttpUriRequest getRequest(String url, Map<String, String> strParams, Map<String, String> fileParams, HttpMethod method) {
		if (method.equals(HttpMethod.POST)) {
			try {
				MultipartEntity multiEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);

				// 装配字符串参数
				StringBuffer sb = new StringBuffer();
				if (strParams != null) {
					TreeMap<String, String> treeMap = new TreeMap<String, String>(strParams);
					for (String name : treeMap.keySet()) {
						Logger.i(name + " = " + treeMap.get(name));
						multiEntity.addPart(name, new StringBody(treeMap.get(name), Charset.forName("UTF-8")));
					}
					Iterator<String> it = treeMap.keySet().iterator();
					while (it.hasNext()) {
						sb.append("&");
						String key = it.next();
						String value = treeMap.get(key);
						
						sb.append(key);
						sb.append("=");
						sb.append(value);
					}
				}
				// 装配文件参数(包括图片)
				if (fileParams != null) {
					for (String name : fileParams.keySet()) {
						File file = new File(fileParams.get(name));
						if (file.exists()) {
							FileBody filebody = new FileBody(file);
							multiEntity.addPart(name, filebody);
						}
					}
				}
				HttpPost request = new HttpPost(url);
				String str = sb.toString();
				if (null != str && str.startsWith("&")) {
					str = str.substring(1);
				}
//				try {
//					str = URLDecoder.decode(str, "utf-8");
//				} catch (Exception e) {
//					e.printStackTrace();
//					Message msg = new Message();
//					msg.what = -1;
//					NwConnect.this.hdl.sendMessage(msg);
//					return null;
//				}
				// 加密
				String sign = Base64.encode(HMacMD5.getHmacMd5Byte(CommonData.MD5KEY, str));
				request.addHeader("sign", sign);
//				request.addHeader("machinekey", SplashActivity.mMachineKey);
				request.setEntity(multiEntity);
				return request;
			} catch (Exception e) {
				e.printStackTrace();
				Message msg = new Message();
				msg.what = -1;
				msg.obj = e.getMessage();
				NwConnect.this.hdl.sendMessage(msg);
				return null;
			}
		} else {
			if (url.indexOf("?") < 0) {
				url += "?";
			}
			if (strParams != null) {
				TreeMap<String, String> treeMap = new TreeMap<String, String>(strParams);
				for (String name : treeMap.keySet()) {
					try {
						url += "&" + name + "=" + URLEncoder.encode(treeMap.get(name), "utf-8");
					} catch (UnsupportedEncodingException e) {
						e.printStackTrace();
					}
				}
			}
			HttpGet request = new HttpGet(url);
			// if (url.contains("?")) {
			// String str = url.substring(url.indexOf("?") + 1);
			// String sign =
			// Base64.encode(HMacMD5.getHmacMd5Byte(CommonData.MD5KEY,
			// str));
			// request.addHeader("sign", sign);
			// }
			return request;
		}
	}

	/*public abstract class HttpConnectionCallback {
		*//**
		 * 处理请求后返回的回调函数
		 * 
		 * @param response
		 *//*
		public abstract void execute(String response);
		public void error(String errmsg){};
	}*/

	Handler hdl = new Handler() {
		@Override
		public void handleMessage(android.os.Message msg) {
			switch (msg.what) {
			case PARSE_JSON:
				if (msg.obj != null) {
					String json = (String) msg.obj;
					if (CommonData.DEBUG) {
						System.out.println(json);
					}
					mCallBack.execute(json);
				} else {
					mCallBack.execute(null);
				}
				break;
			case -1:
				if (mCallBack != null) {
					String errorString = (String) msg.obj;
					mCallBack.onError(-1, errorString);
				}
				break;
			}
		}
	};
}
